package com.nkym.wypan.aspect;/*
 * @ClassName LoginAspect
 * @Desc TODO
 * @Author 19637
 * @Date 2023/6/8 14:04
 * @Version 1.0
 */

import com.nkym.wypan.annotation.LoginIgnore;
import com.nkym.wypan.enums.ResponseStatus;
import com.nkym.wypan.exception.BusinessException;
import com.nkym.wypan.service.UserService;
import com.nkym.wypan.utils.JwtUtils;
import com.nkym.wypan.utils.UserContextHolder;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;


import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Optional;

@Aspect
@Component
public class LoginAspect {

    public static final String AUTHORIZATION_HEADER = "Authorization";
    public static final String AUTHORIZATION_SCHEMA = "Bearer ";

    @Resource
    UserService userService;

    @Pointcut("execution(public * com.nkym.wypan.controller.*Controller.*(..))")
    public void pointCut() {
    }


    @Around("pointCut()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (requestAttributes == null) {
            throw new BusinessException(ResponseStatus.FAIL);
        }
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Method method = signature.getMethod();
        LoginIgnore annotation = method.getAnnotation(LoginIgnore.class);
        if (annotation != null) {
            return pjp.proceed();
        }
        HttpServletRequest request = requestAttributes.getRequest();
        String token = getToken(request);
        Long uid = userService.getUserId(token);
        if (uid == null) {
            throw new BusinessException(ResponseStatus.USER_NOT_LOGIN);
        }
        UserContextHolder.setId(uid);
        return pjp.proceed();
    }

    private String getToken(HttpServletRequest request) {
        String header = request.getHeader(AUTHORIZATION_HEADER);
        return Optional.ofNullable(header)
                .filter(h -> h.startsWith(AUTHORIZATION_SCHEMA))
                .map(h -> h.substring(AUTHORIZATION_SCHEMA.length()))
                .orElse(null);
    }
}
